<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>🔄 Agent协作数据流可视化</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1600px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }

        .header h1 {
            font-size: 28px;
            margin-bottom: 10px;
        }

        .header p {
            opacity: 0.9;
            font-size: 16px;
        }

        .main-content {
            display: flex;
            min-height: 80vh;
        }

        .left-panel {
            flex: 1;
            padding: 30px;
            border-right: 1px solid #e9ecef;
            background: #fafafa;
        }

        .right-panel {
            flex: 2;
            padding: 30px;
            background: white;
        }

        .control-section {
            margin-bottom: 30px;
        }

        .control-group {
            margin-bottom: 20px;
        }

        .control-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
        }

        .control-input {
            width: 100%;
            padding: 12px 15px;
            border: 2px solid #e9ecef;
            border-radius: 10px;
            font-size: 16px;
            outline: none;
            transition: border-color 0.3s;
        }

        .control-input:focus {
            border-color: #4facfe;
        }

        .start-btn {
            width: 100%;
            padding: 15px;
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            border: none;
            border-radius: 10px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: transform 0.2s;
        }

        .start-btn:hover {
            transform: translateY(-2px);
        }

        .start-btn:disabled {
            background: #ccc;
            cursor: not-allowed;
            transform: none;
        }

        .status-panel {
            background: white;
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        .status-title {
            font-size: 18px;
            font-weight: 600;
            margin-bottom: 15px;
            color: #333;
        }

        .agent-status {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        .agent-name {
            font-weight: 500;
        }

        .status-indicator {
            width: 12px;
            height: 12px;
            border-radius: 50%;
        }

        .status-online {
            background: #4caf50;
        }

        .status-offline {
            background: #f44336;
        }

        .data-flow-visualization {
            height: 100%;
            position: relative;
        }

        .flow-timeline {
            position: relative;
            padding-left: 50px;
        }

        .timeline-line {
            position: absolute;
            left: 25px;
            top: 0;
            bottom: 0;
            width: 3px;
            background: linear-gradient(to bottom, #4facfe, #00f2fe);
            border-radius: 2px;
        }

        .flow-step {
            position: relative;
            margin-bottom: 30px;
            opacity: 0;
            animation: fadeInUp 0.6s ease-out forwards;
        }

        .flow-step:nth-child(1) { animation-delay: 0.1s; }
        .flow-step:nth-child(2) { animation-delay: 0.2s; }
        .flow-step:nth-child(3) { animation-delay: 0.3s; }
        .flow-step:nth-child(4) { animation-delay: 0.4s; }
        .flow-step:nth-child(5) { animation-delay: 0.5s; }

        @keyframes fadeInUp {
            from {
                opacity: 0;
                transform: translateY(20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .step-node {
            position: absolute;
            left: -40px;
            top: 0;
            width: 35px;
            height: 35px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 16px;
            color: white;
            z-index: 2;
        }

        .step-card {
            background: white;
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            border-left: 4px solid #4facfe;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }

        .step-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(0,0,0,0.15);
        }

        .step-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .step-title {
            font-size: 18px;
            font-weight: 600;
            color: #333;
        }

        .step-time {
            font-size: 12px;
            color: #666;
        }

        .step-agent {
            display: inline-block;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: 500;
            margin-bottom: 10px;
        }

        .step-content {
            color: #555;
            line-height: 1.6;
            margin-bottom: 15px;
        }

        .data-section {
            margin-bottom: 15px;
        }

        .data-label {
            font-weight: 600;
            color: #333;
            margin-bottom: 8px;
            display: flex;
            align-items: center;
        }

        .data-label::before {
            content: "📊";
            margin-right: 8px;
        }

        .data-content {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 12px;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            color: #333;
            max-height: 120px;
            overflow-y: auto;
            border: 1px solid #e9ecef;
        }

        .flow-arrow {
            text-align: center;
            margin: 15px 0;
            color: #666;
            font-size: 24px;
            animation: bounce 2s infinite;
        }

        @keyframes bounce {
            0%, 20%, 50%, 80%, 100% {
                transform: translateY(0);
            }
            40% {
                transform: translateY(-5px);
            }
            60% {
                transform: translateY(-3px);
            }
        }

        .negotiation-highlight {
            background: linear-gradient(135deg, #fff3e0 0%, #ffffff 100%);
            border-left-color: #ff9800;
        }

        .conflict-highlight {
            background: linear-gradient(135deg, #ffebee 0%, #ffffff 100%);
            border-left-color: #f44336;
        }

        .agreement-highlight {
            background: linear-gradient(135deg, #e8f5e8 0%, #ffffff 100%);
            border-left-color: #4caf50;
        }

        .progress-section {
            margin-top: 30px;
            text-align: center;
        }

        .progress-bar {
            width: 100%;
            height: 8px;
            background: #e9ecef;
            border-radius: 4px;
            margin: 20px 0;
            overflow: hidden;
        }

        .progress-fill {
            height: 100%;
            background: linear-gradient(90deg, #4facfe, #00f2fe);
            width: 0%;
            transition: width 0.5s ease;
            border-radius: 4px;
        }

        .progress-text {
            font-size: 14px;
            color: #666;
        }

        .stats-panel {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin-top: 30px;
        }

        .stat-card {
            background: white;
            border-radius: 15px;
            padding: 20px;
            text-align: center;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        .stat-value {
            font-size: 32px;
            font-weight: 700;
            color: #4facfe;
            margin-bottom: 5px;
        }

        .stat-label {
            font-size: 14px;
            color: #666;
            text-transform: uppercase;
            letter-spacing: 1px;
        }

        .thinking-animation {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 2px solid #ff9800;
            border-radius: 50%;
            border-top-color: transparent;
            animation: spin 1s linear infinite;
            margin-right: 10px;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .agent-avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 18px;
            margin-right: 15px;
            flex-shrink: 0;
        }

        .coordinator-avatar { background: linear-gradient(135deg, #2196f3, #21cbf3); }
        .weather-avatar { background: linear-gradient(135deg, #4caf50, #81c784); }
        .budget-avatar { background: linear-gradient(135deg, #ff9800, #ffb74d); }
        .travel-avatar { background: linear-gradient(135deg, #9c27b0, #ba68c8); }
        .restaurant-avatar { background: linear-gradient(135deg, #f44336, #ef5350); }

        /* 响应式设计 */
        @media (max-width: 768px) {
            .main-content {
                flex-direction: column;
            }

            .left-panel, .right-panel {
                flex: none;
                padding: 20px;
            }

            .header {
                padding: 20px;
            }

            .header h1 {
                font-size: 24px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🔄 Agent协作数据流可视化</h1>
            <p>实时查看智能体间的思考过程、数据传递和协商决策</p>
        </div>

        <div class="main-content">
            <!-- 左侧控制面板 -->
            <div class="left-panel">
                <div class="control-section">
                    <div class="control-group">
                        <label for="userQuery">💬 用户查询</label>
                        <input type="text" id="userQuery" class="control-input"
                               placeholder="例如：我想去北京旅行3天，预算800欧元"
                               value="我想去北京旅行3天，预算800欧元，喜欢历史景点和美食，对天气比较敏感">
                    </div>

                    <button class="start-btn" id="startBtn" onclick="startDataFlow()">
                        🚀 开始数据流演示
                    </button>
                </div>

                <div class="status-panel">
                    <div class="status-title">🤖 Agent状态监控</div>

                    <div class="agent-status">
                        <span class="agent-name">🎯 CoordinatorAgent</span>
                        <div class="status-indicator status-online" id="coordinatorStatus"></div>
                    </div>

                    <div class="agent-status">
                        <span class="agent-name">🌤️ WeatherAgent</span>
                        <div class="status-indicator status-offline" id="weatherStatus"></div>
                    </div>

                    <div class="agent-status">
                        <span class="agent-name">💰 BudgetAgent</span>
                        <div class="status-indicator status-offline" id="budgetStatus"></div>
                    </div>

                    <div class="agent-status">
                        <span class="agent-name">🗺️ TravelAgent</span>
                        <div class="status-indicator status-offline" id="travelStatus"></div>
                    </div>

                    <div class="agent-status">
                        <span class="agent-name">🍽️ RestaurantAgent</span>
                        <div class="status-indicator status-offline" id="restaurantStatus"></div>
                    </div>
                </div>

                <div class="stats-panel">
                    <div class="stat-card">
                        <div class="stat-value" id="totalSteps">0</div>
                        <div class="stat-label">数据流步骤</div>
                    </div>

                    <div class="stat-card">
                        <div class="stat-value" id="activeAgents">0</div>
                        <div class="stat-label">活跃Agent</div>
                    </div>

                    <div class="stat-card">
                        <div class="stat-value" id="dataTransfers">0</div>
                        <div class="stat-label">数据传递</div>
                    </div>
                </div>
            </div>

            <!-- 右侧数据流可视化面板 -->
            <div class="right-panel">
                <div class="data-flow-visualization">
                    <div class="flow-timeline" id="flowTimeline">
                        <div class="timeline-line"></div>

                        <!-- 欢迎信息 -->
                        <div class="flow-step" id="welcomeStep">
                            <div class="step-node" style="background: linear-gradient(135deg, #4facfe, #00f2fe);">🎯</div>
                            <div class="step-card">
                                <div class="step-header">
                                    <div class="step-title">欢迎使用Agent数据流可视化</div>
                                    <div class="step-time">--:--:--</div>
                                </div>
                                <div class="step-content">
                                    这个界面将实时展示Agent间的协作过程，包括：
                                    <ul style="margin-top: 10px;">
                                        <li>📥 数据输入和处理</li>
                                        <li>🔄 Agent间的数据传递</li>
                                        <li>🤝 协商和冲突解决</li>
                                        <li>📤 最终结果输出</li>
                                    </ul>
                                    <br>
                                    请在左侧输入您的旅行需求，然后点击"开始演示"按钮。
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="progress-section">
                        <div class="progress-bar">
                            <div class="progress-fill" id="progressFill"></div>
                        </div>
                        <div class="progress-text" id="progressText">等待开始...</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 全局变量
        let currentStep = 0;
        let activeTimers = [];
        let isRunning = false;

        // DOM元素
        const flowTimeline = document.getElementById('flowTimeline');
        const progressFill = document.getElementById('progressFill');
        const progressText = document.getElementById('progressText');
        const startBtn = document.getElementById('startBtn');

        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            checkAgentsStatus();
            setInterval(checkAgentsStatus, 5000);
        });

        // 开始数据流演示
        function startDataFlow() {
            if (isRunning) return;

            const userQuery = document.getElementById('userQuery').value.trim();
            if (!userQuery) {
                alert('请输入用户查询！');
                return;
            }

            isRunning = true;
            startBtn.disabled = true;
            startBtn.textContent = '🔄 演示进行中...';

            // 清空现有步骤（保留欢迎信息）
            const steps = flowTimeline.querySelectorAll('.flow-step:not(#welcomeStep)');
            steps.forEach(step => step.remove());

            // 重置统计
            currentStep = 0;
            updateStats(0, 0, 0);
            updateProgress(0, '开始分析用户需求...');

            // 开始演示流程
            runDataFlowDemo(userQuery);
        }

        // 运行数据流演示
        function runDataFlowDemo(userQuery) {
            const demoSteps = [
                {
                    delay: 1000,
                    nodeIcon: '🎯',
                    nodeColor: 'linear-gradient(135deg, #2196f3, #21cbf3)',
                    title: 'CoordinatorAgent: 需求分析',
                    agent: 'CoordinatorAgent',
                    content: `正在分析用户需求：${userQuery}`,
                    data: {
                        input: {
                            type: 'user_query',
                            content: userQuery,
                            timestamp: new Date().toISOString()
                        },
                        processing: '意图识别、实体提取、需求分类'
                    }
                },
                {
                    delay: 2500,
                    nodeIcon: '🌤️',
                    nodeColor: 'linear-gradient(135deg, #4caf50, #81c784)',
                    title: 'WeatherAgent: 天气数据获取',
                    agent: 'WeatherAgent',
                    content: 'CoordinatorAgent将用户需求转发给WeatherAgent进行天气影响分析',
                    data: {
                        input: {
                            type: 'collaboration_request',
                            user_requirements: {
                                location: '北京',
                                duration: '3天',
                                weather_sensitivity: 'high'
                            },
                            collaboration_context: {
                                purpose: 'travel_planning'
                            }
                        },
                        output: {
                            type: 'weather_analysis',
                            current_weather: '多云，27.65°C',
                            forecast_3day: [
                                { date: '2025-09-11', condition: 'partly_cloudy', temp_high: 28, temp_low: 18 },
                                { date: '2025-09-12', condition: 'rainy', temp_high: 22, temp_low: 15 },
                                { date: '2025-09-13', condition: 'sunny', temp_high: 26, temp_low: 17 }
                            ],
                            impact_analysis: {
                                outdoor_suitability: '中等',
                                indoor_recommendation: true,
                                cost_impact: '雨天可能增加交通成本'
                            }
                        }
                    }
                },
                {
                    delay: 4000,
                    nodeIcon: '💰',
                    nodeColor: 'linear-gradient(135deg, #ff9800, #ffb74d)',
                    title: 'BudgetAgent: 预算分析与协商',
                    agent: 'BudgetAgent',
                    content: 'WeatherAgent的结果传递给BudgetAgent，分析预算分配并发现冲突',
                    data: {
                        input: {
                            type: 'collaboration_request',
                            user_requirements: {
                                budget: '800欧元',
                                location: '北京',
                                duration: '3天'
                            },
                            upstream_context: {
                                weather_impact: {
                                    extra_transportation_cost: 50,
                                    weather_condition: '多云转雨',
                                    indoor_preference: true
                                }
                            }
                        },
                        conflicts: [
                            '预算紧张：天气因素增加50€成本',
                            '用户偏好 vs 预算限制的冲突'
                        ],
                        negotiation_points: [
                            {
                                target_agent: 'WeatherAgent',
                                topic: 'budget_constraint_resolution',
                                proposal: '需要天气建议来优化预算分配'
                            }
                        ]
                    },
                    highlight: 'negotiation-highlight'
                },
                {
                    delay: 5500,
                    nodeIcon: '🤝',
                    nodeColor: 'linear-gradient(135deg, #ff9800, #ffb74d)',
                    title: 'Agent间协商过程',
                    agent: 'BudgetAgent ↔ WeatherAgent',
                    content: 'BudgetAgent发现预算冲突，发起与WeatherAgent的协商',
                    data: {
                        negotiation_request: {
                            sender: 'BudgetAgent',
                            issue: '预算不足80€，需要成本优化方案',
                            proposals: [
                                '推荐免费/低成本的北京景点',
                                '雨天的室内免费活动推荐'
                            ]
                        },
                        negotiation_response: {
                            sender: 'WeatherAgent',
                            solutions: [
                                {
                                    category: '免费景点',
                                    options: ['天坛公园', '雍和宫', '什刹海'],
                                    savings: '45€'
                                },
                                {
                                    category: '低成本交通',
                                    options: ['地铁日票', '步行+公交'],
                                    savings: '35€'
                                }
                            ],
                            total_savings: '80€',
                            status: 'agreement_reached'
                        }
                    },
                    highlight: 'conflict-highlight'
                },
                {
                    delay: 7000,
                    nodeIcon: '🗺️',
                    nodeColor: 'linear-gradient(135deg, #9c27b0, #ba68c8)',
                    title: 'TravelAgent: 景点推荐',
                    agent: 'TravelAgent',
                    content: '基于天气和预算分析，TravelAgent生成个性化景点推荐',
                    data: {
                        input: {
                            city: '北京',
                            weather_analysis: '雨天室内优先',
                            budget_constraints: '控制在850€以内'
                        },
                        recommendations: [
                            {
                                name: '故宫博物院',
                                type: '历史景点',
                                reason: '室内历史展览，适合雨天',
                                estimated_cost: '60€'
                            },
                            {
                                name: '天坛公园',
                                type: '皇家园林',
                                reason: '免费景点，雨天室内殿堂',
                                estimated_cost: '0€'
                            },
                            {
                                name: '雍和宫',
                                type: '寺庙',
                                reason: '免费参观，室内古建筑',
                                estimated_cost: '0€'
                            }
                        ]
                    }
                },
                {
                    delay: 8500,
                    nodeIcon: '🍽️',
                    nodeColor: 'linear-gradient(135deg, #f44336, #ef5350)',
                    title: 'RestaurantAgent: 餐厅推荐',
                    agent: 'RestaurantAgent',
                    content: '根据景点位置和预算，RestaurantAgent推荐美食餐厅',
                    data: {
                        input: {
                            city: '北京',
                            based_on_attractions: ['故宫博物院', '天坛公园', '雍和宫'],
                            budget_constraints: '中等价位，控制餐饮预算'
                        },
                        recommendations: [
                            {
                                name: '全聚德(前门店)',
                                type: '北京烤鸭',
                                price_range: '中档',
                                location_reason: '靠近故宫博物院',
                                estimated_cost: '45€'
                            },
                            {
                                name: '海碗居',
                                type: '老北京菜',
                                price_range: '平价',
                                location_reason: '靠近天坛公园',
                                estimated_cost: '25€'
                            },
                            {
                                name: '锦馨豆花庄',
                                type: '豆花饭庄',
                                price_range: '平价',
                                location_reason: '雍和宫附近特色小吃',
                                estimated_cost: '15€'
                            }
                        ]
                    }
                },
                {
                    delay: 10000,
                    nodeIcon: '✅',
                    nodeColor: 'linear-gradient(135deg, #4caf50, #81c784)',
                    title: 'CoordinatorAgent: 最终结果整合',
                    agent: 'CoordinatorAgent',
                    content: '整合所有Agent的结果，生成完整的旅行规划方案',
                    data: {
                        final_result: {
                            user_query: userQuery,
                            weather_info: '多云转雨，建议室内活动优先',
                            budget_plan: {
                                total_budget: '850€',
                                breakdown: {
                                    accommodation: '240€',
                                    food: '240€',
                                    transportation: '130€',
                                    activities: '160€',
                                    emergency: '30€'
                                }
                            },
                            itinerary: {
                                day1: ['故宫博物院', '全聚德烤鸭'],
                                day2: ['天坛公园', '海碗居'],
                                day3: ['雍和宫', '锦馨豆花庄']
                            },
                            negotiation_summary: {
                                total_negotiations: 1,
                                resolved_issues: 1,
                                total_savings: '80€',
                                success_rate: '100%'
                            }
                        }
                    },
                    highlight: 'agreement-highlight'
                }
            ];

            // 执行每个步骤
            demoSteps.forEach((step, index) => {
                const timerId = setTimeout(() => {
                    if (!isRunning) return;

                    addFlowStep(step);
                    updateProgress((index + 1) / demoSteps.length * 100,
                                 `步骤 ${index + 1}/${demoSteps.length}: ${step.title}`);

                    // 更新统计
                    updateStats(index + 1, Math.min(index + 1, 5), (index + 1) * 2);

                }, step.delay);
                activeTimers.push(timerId);
            });

            // 演示完成
            const completionTimer = setTimeout(() => {
                if (!isRunning) return;

                updateProgress(100, '演示完成！所有Agent协作流程已展示');
                startBtn.disabled = false;
                startBtn.textContent = '🎉 重新演示';
                isRunning = false;

            }, 11000);
            activeTimers.push(completionTimer);
        }

        // 添加数据流步骤
        function addFlowStep(step) {
            const stepDiv = document.createElement('div');
            stepDiv.className = `flow-step ${step.highlight || ''}`;

            const currentTime = new Date().toLocaleTimeString();

            stepDiv.innerHTML = `
                <div class="step-node" style="background: ${step.nodeColor}">${step.nodeIcon}</div>
                <div class="step-card">
                    <div class="step-header">
                        <div class="step-title">${step.title}</div>
                        <div class="step-time">${currentTime}</div>
                    </div>
                    <div class="step-agent">${step.agent}</div>
                    <div class="step-content">${step.content}</div>

                    ${step.data.input ? `
                    <div class="data-section">
                        <div class="data-label">📥 输入数据</div>
                        <div class="data-content">${formatData(step.data.input)}</div>
                    </div>
                    ` : ''}

                    ${step.data.output ? `
                    <div class="data-section">
                        <div class="data-label">📤 输出数据</div>
                        <div class="data-content">${formatData(step.data.output)}</div>
                    </div>
                    ` : ''}

                    ${step.data.conflicts ? `
                    <div class="data-section">
                        <div class="data-label">⚠️ 发现冲突</div>
                        <div class="data-content">${formatData(step.data.conflicts)}</div>
                    </div>
                    ` : ''}

                    ${step.data.negotiation_points ? `
                    <div class="data-section">
                        <div class="data-label">🤝 协商要点</div>
                        <div class="data-content">${formatData(step.data.negotiation_points)}</div>
                    </div>
                    ` : ''}

                    ${step.data.negotiation_request ? `
                    <div class="data-section">
                        <div class="data-label">📨 协商请求</div>
                        <div class="data-content">${formatData(step.data.negotiation_request)}</div>
                    </div>
                    ` : ''}

                    ${step.data.negotiation_response ? `
                    <div class="data-section">
                        <div class="data-label">📬 协商响应</div>
                        <div class="data-content">${formatData(step.data.negotiation_response)}</div>
                    </div>
                    ` : ''}

                    ${step.data.recommendations ? `
                    <div class="data-section">
                        <div class="data-label">🎯 推荐结果</div>
                        <div class="data-content">${formatData(step.data.recommendations)}</div>
                    </div>
                    ` : ''}

                    ${step.data.final_result ? `
                    <div class="data-section">
                        <div class="data-label">🎉 最终结果</div>
                        <div class="data-content">${formatData(step.data.final_result)}</div>
                    </div>
                    ` : ''}
                </div>
            `;

            flowTimeline.appendChild(stepDiv);

            // 滚动到底部
            flowTimeline.scrollTop = flowTimeline.scrollHeight;

            currentStep++;
        }

        // 格式化数据展示
        function formatData(data) {
            if (typeof data === 'string') {
                return data;
            }

            // 对于复杂对象，进行格式化
            if (Array.isArray(data)) {
                return data.map((item, index) =>
                    `• ${typeof item === 'object' ? JSON.stringify(item, null, 2) : item}`
                ).join('\n');
            }

            // 对于对象，进行JSON格式化
            return JSON.stringify(data, null, 2);
        }

        // 更新进度
        function updateProgress(percentage, text) {
            progressFill.style.width = `${percentage}%`;
            progressText.textContent = text || `${Math.round(percentage)}%`;
        }

        // 更新统计
        function updateStats(steps, agents, transfers) {
            document.getElementById('totalSteps').textContent = steps;
            document.getElementById('activeAgents').textContent = agents;
            document.getElementById('dataTransfers').textContent = transfers;
        }

        // 检查Agent状态
        async function checkAgentsStatus() {
            try {
                const response = await fetch('http://localhost:8000/api/agents/status');
                const agents = await response.json();

                updateAgentStatus('coordinatorStatus', agents.coordinator?.status === '在线');
                updateAgentStatus('weatherStatus', agents.weather?.status === '在线');
                updateAgentStatus('budgetStatus', agents.budget?.status === '在线');
                updateAgentStatus('travelStatus', agents.travel?.status === '在线');
                updateAgentStatus('restaurantStatus', agents.restaurant?.status === '在线');

            } catch (error) {
                console.error('检查Agent状态失败:', error);
                // 设置所有为离线状态
                updateAgentStatus('coordinatorStatus', false);
                updateAgentStatus('weatherStatus', false);
                updateAgentStatus('budgetStatus', false);
                updateAgentStatus('travelStatus', false);
                updateAgentStatus('restaurantStatus', false);
            }
        }

        // 更新Agent状态指示器
        function updateAgentStatus(elementId, isOnline) {
            const indicator = document.getElementById(elementId);
            if (isOnline) {
                indicator.className = 'status-indicator status-online';
            } else {
                indicator.className = 'status-indicator status-offline';
            }
        }

        // 停止演示
        function stopDemo() {
            isRunning = false;
            activeTimers.forEach(id => clearTimeout(id));
            activeTimers = [];
            startBtn.disabled = false;
            startBtn.textContent = '🚀 开始数据流演示';
            updateProgress(0, '演示已停止');
        }

        // 添加键盘快捷键
        document.addEventListener('keydown', function(event) {
            if (event.key === 'Escape') {
                stopDemo();
            }
        });
    </script>
</body>
</html>
